﻿using DotCMIS;
using DotCMIS.Client;
using DotCMIS.Client.Impl;
using DotCMIS.Data;
using DotCMIS.Data.Impl;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Numerics;
using DotCMIS.Enums;



namespace CMIS_WEB.Models
{
    public class CMIS_Factory
    {
        public const string ip_server = "http://192.168.32.134:8080";

        public List<Documento> documentos {get; set;}


        public static List<Documento> GetAllDocumentsByFolder(string username, string password, string url_cmis_atompub,string folder)
        {
            List<Documento> resultado = new List<Documento>();
            ISession session = LoginRepository( username,  password,  url_cmis_atompub);
            
            /*IOperationContext folderOpCtx = session.CreateOperationContext();
            folderOpCtx.FilterString="cmis:name, cmis:path";
            folderOpCtx.IncludeAcls = false;
            folderOpCtx.IncludeAllowableActions = false;
            folderOpCtx.IncludePolicies = false;
            folderOpCtx.IncludeRelationships = DotCMIS.Enums.IncludeRelationshipsFlag.None;
            folderOpCtx.IncludePathSegments = false;
            folderOpCtx.OrderBy = null;
            folderOpCtx.CacheEnabled = true;*/

            IItemEnumerable<IQueryResult> results = session.Query("SELECT cmis:objectId FROM cmis:folder WHERE cmis:name='" + folder + "' AND cmis:objectTypeId ='cmis:folder'", false);

            foreach(IQueryResult query in results)
            {
                foreach (IPropertyData prop in query.Properties) 
                {
                    
                    String queryName = prop.QueryName;
                    Object value = prop.FirstValue;

                    ICmisObject carpeta_buscada  = session.GetObject((string)value);
                    IFolder carpetilla = null;

                    if (carpeta_buscada is IFolder)
                    {
                        carpetilla = (Folder)carpeta_buscada;
                        IItemEnumerable<ICmisObject> docs =  carpetilla.GetChildren();
                        
                        
                        foreach(ICmisObject obj in docs)
                        {
                            Documento doc = new Documento();

                            IProperty propdni = null;
                            IProperty propnombre = null;
                            IProperty propapellidos = null;
                            IProperty propidempleado = null;

                            
                            try
                            {
                                propdni = obj.Properties.Where(x => x.LocalName.Equals("DNI")).First<IProperty>();
                                propnombre = obj.Properties.Where(x => x.LocalName.Equals("nombre")).First<IProperty>();
                                propapellidos = obj.Properties.Where(x => x.LocalName.Equals("apellidos")).First<IProperty>();
                                propidempleado = obj.Properties.Where(x => x.LocalName.Equals("numEmpleado")).First<IProperty>();
                            } 
                            catch (Exception ex )
                            {
                                doc.dni = "";
                                doc.apellidos = "";
                                doc.nombre_presona = "";
                                doc.numEmpleado = "";
                            }


                            if (propdni != null && propdni.FirstValue != null)
                            {
                                doc.dni = propdni.Value.ToString();
                            }
                            if (propnombre != null && propnombre.FirstValue != null)
                            {
                                doc.nombre_presona = propnombre.Value.ToString();
                            }
                            if (propapellidos != null && propapellidos.FirstValue !=null)
                            {
                                doc.apellidos = propapellidos.Value.ToString();
                            }
                            if (propidempleado != null && propidempleado.FirstValue != null)
                            {
                                doc.numEmpleado = propidempleado.Value.ToString();
                            }
                            doc.iddocumento = obj.Id;
                            String [] param= {"//"};

                            doc.documento = ip_server+"/alfresco/d/a/" + obj.Id.Replace("workspace://","workspace/")+ "/" + obj.Name;
                            doc.url_visualizar = ip_server+"/alfresco/d/d/" + obj.Id.Replace("workspace://", "workspace/") + "/" + obj.Name;
                            resultado.Add(doc);
                        }
                    }
                    
                }

            }

            return resultado;
        }

        public static ISession LoginRepository(string username, string password, string url_cmis_atompub)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();

            parameters[SessionParameter.BindingType] = BindingType.AtomPub;
            parameters[SessionParameter.AtomPubUrl] = url_cmis_atompub;
            parameters[SessionParameter.User] = username;
            parameters[SessionParameter.Password] = password;

            SessionFactory factory = SessionFactory.NewInstance();
            ISession session = null;
            try 
            { 
               session = factory.GetRepositories(parameters)[0].CreateSession();
               }
               catch(Exception ex)
               {
                   if (ex.Message.Equals("ConnectFailure"))
                   {
                       throw new Exception("No es posible establecer la conexión con el gestor documental");
                   }
               }
               return session;
        }


        public static string borrar_documento (string username, string password, string url_cmis_atompub,string doc_id)
        {
            IDocument doc_to_erase = null;
            ISession session = LoginRepository( username,  password,  url_cmis_atompub);
            try
            {
                ICmisObject obj= session.GetObject(doc_id);
                if (obj is IDocument)
                {
                    doc_to_erase = (IDocument)obj;
                    doc_to_erase.Delete(true);
                }
                else
                {
                    throw new Exception("BORRAR DOCUMENTO: ERROR :: No se puede borrar el archivo con id " + doc_id + " .El objeto no es de tipo 'Document'. Por favor, revisar el id de objeto que se pasa por parámetros");
                }

            }
            catch (Exception ex)
            {
                return ("ERROR en Borrar Documento:" + ex.Message + "\n" + ex.StackTrace);
            }
            
            return "OK";
        }

        public static string crearDocumento(ISession session, string carpetaId_objetivo, Documento doc_atributos, string filePath)
        {
            try
            {
                String nombrefichero = doc_atributos.numEmpleado + ".pdf";

                IItemEnumerable<IQueryResult> results = session.Query("SELECT cmis:objectId FROM cmis:folder WHERE cmis:name='" + carpetaId_objetivo + "' AND cmis:objectTypeId ='cmis:folder'", false);

                Folder carpetaObjetivo = null;

                foreach (IQueryResult query in results)
                {
                    foreach (IPropertyData prop in query.Properties)
                    {

                        String queryName = prop.QueryName;
                        Object value = prop.FirstValue;

                        ICmisObject obj = session.GetObject((string)value);
                        
                        if (obj is IFolder)
                            carpetaObjetivo = (Folder)obj;
                        else
                            throw new Exception("CREAR DOCUMENTO: ERROR :: No se puede subir el archivo " + nombrefichero + " .La carpeta objetivo no es de tipo 'Folder'. Por favor, revisar el id de objeto que se pasa por parámetros");
                    }
                }

                
                

                Dictionary<String, Object> properties = new Dictionary<string, object>();
                properties.Add(PropertyIds.ObjectTypeId, "D:iaflacaixa:Product");
                //properties.Add(PropertyIds.ObjectTypeId, "cmis:document");
                properties.Add(PropertyIds.Name, nombrefichero);
                properties.Add(PropertyIds.ContentStreamMimeType, "application/pdf");
                properties.Add("iaflacaixa:numEmpleado", System.Convert.ToInt32(doc_atributos.numEmpleado));
                properties.Add("iaflacaixa:DNI", doc_atributos.dni);
                properties.Add("iaflacaixa:nombre", doc_atributos.nombre_presona);
                properties.Add("iaflacaixa:apellidos", doc_atributos.apellidos);


                byte[] fichero = File.ReadAllBytes(filePath);
                Stream stream = new MemoryStream(fichero);
                ContentStream contentStream = new ContentStream();
                contentStream.Length = fichero.Length;
                contentStream.FileName = nombrefichero;
                contentStream.MimeType = "application/pdf";
                contentStream.Stream = stream;

                IDocument newdoc = carpetaObjetivo.CreateDocument(properties, contentStream,VersioningState.Major);
                
            }catch(Exception ex)
            {
                return ("ERROR en Crear Documento:"+ex.Message+"\n"+ex.StackTrace);
            }

            return "OK";
        }
    }
}